#include "stdafx.h"
#include "problem_solver_core.h"
#include "problem.h"
#include "layer.h"
#include "input_layer.h"
#include "neuron.h"
#include "input_neuron.h"
#include "bias_unit.h"

namespace nnse
{
	extern io_module io_m;

	// Constructor and Destructor

	template <class T, class U> input_layer<T, U>::input_layer(MLP<T, U>^ p, unsigned int l_n)
	: layer(p, l_n)
	{
		io_m.startup_stream << "Constructing input layer " << get_number() << std::endl;
		put_number_of_neurons(get_parent_problem()->get_number_of_inputs()+1);
		put_neurons();
	}

	template <class T, class U> input_layer<T, U>::~input_layer()
	{
		io_m.startup_stream << "Destructing input layer " << get_number() << std::endl;
	}

	// Accessor Functions

	template <class T, class U> void input_layer<T, U>::put_neurons()
	{
		neurons=gcnew array<input_neuron<T, U>^>(get_number_of_neurons());
		for (unsigned int n_n=0; n_n<get_number_of_neurons()-1; n_n++)
		{
			neurons[n_n]=gcnew input_neuron<T, U>(this, n_n);
		}
		neurons[get_number_of_neurons()-1]=gcnew bias_unit<T, U>(this, get_number_of_neurons()-1);
	}

	// Worker Functions

	template <class T, class U> inline U input_layer<T, U>::reverse(layer<T, U>% dummy_next_layer)
	{
		return 0.0;
	}

	// Serialisation Functions

	template <class T, class U> void input_layer<T, U>::display(std::wofstream& out)
	{
		out << "Input Layer:" << std::endl;
		layer<T, U>::display(out);
	}

	// Explicit Instantiation

	template ref class input_layer<bool, double>;
	template ref class input_layer<unsigned char, double>;
}
